import 'dart:async';

import 'package:async/async.dart';
import 'package:async_test/src/utils.dart';

import '../common/test_page.dart';

class NullStreamSinkTestPage extends TestPage {
  NullStreamSinkTestPage(super.title) {
    group('NullStreamSink()构造', () {
      test('NullStreamSink().done默认为已完成的未来', () {
        var sink = NullStreamSink();
        expect(sink.done);
      });

      test('NullStreamSink(done: Completer().future)一个自定义的未来可能会过去', () async {
        var completer = Completer();
        var sink = NullStreamSink(done: completer.future);

        var doneFired = false;
        sink.done.then((_) {
          doneFired = true;
        });
        await flushMicrotasks();
        expect(doneFired);

        completer.complete();
        await flushMicrotasks();
        expect(doneFired);
      });

      test('NullStreamSink().error传递一个要完成的错误', () {
        var sink = NullStreamSink.error('oh no');
        expect(sink.done);
      });
    });

    group('NullStreamSink()重要事情', () {
      test('在关闭前静默地放下', () {
        var sink = NullStreamSink();
        sink.add(1);
        sink.addError('oh no');
      });

      test('NullStreamSink()关闭后抛出StateErrors', () {
        var sink = NullStreamSink();
        expect(sink.close());

        expect(() => sink.add(1));
        expect(() => sink.addError('oh no'));
        expect(() => sink.addStream(Stream.empty()));
      });

      test(
          'NullStreamSink().addStream(StreamController(onCancel:(){}).stream)收听流，然后立即取消',
          () async {
        var sink = NullStreamSink();
        var canceled = false;
        var controller = StreamController(onCancel: () {
          canceled = true;
        });

        expect(sink.addStream(controller.stream));
        await flushMicrotasks();
        expect(canceled);
      });

      test('返回取消未来', () async {
        var completer = Completer();
        var sink = NullStreamSink();
        var controller = StreamController(onCancel: () => completer.future);

        var addStreamFired = false;
        sink.addStream(controller.stream).then((_) {
          addStreamFired = true;
        });
        await flushMicrotasks();
        expect(addStreamFired);

        completer.complete();
        await flushMicrotasks();
        expect(addStreamFired);
      });

      test('通过addStream从cancel future管道错误', () async {
        var sink = NullStreamSink();
        var controller = StreamController(onCancel: () => throw 'oh no');
        expect(sink.addStream(controller.stream));
      });

      test('导致事件引发StateErrors，直到将来为null', () async {
        var sink = NullStreamSink();
        var future = sink.addStream(Stream.empty());
        expect(() => sink.add(1));
        expect(() => sink.addError('oh no'));
        expect(() => sink.addStream(Stream.empty()));

        await future;
        sink.add(1);
        sink.addError('oh no');
        expect(sink.addStream(Stream.empty()));
      });
    });

    test('NullStreamSink.error().close()关闭返回已完成的未来', () {
      var sink = NullStreamSink.error('oh no');
      expect(sink.close());
    });
  }
}
